package com.jackstraw.jack_base.mq.common.entity;

import com.jackstraw.jack_base.util.CollectionUtil;
import com.jackstraw.jack_base.util.ObjectUtil;
import com.jackstraw.jack_base.util.StringUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * MQ单项配置
 *
 * @param <P> 生产者
 * @param <C> 消费者
 */
@Data
@Slf4j
public abstract class MQEntity<P extends MQProducer,
        C extends MQConsumer,
        MTS extends MQTemplateS,
        ME extends MQEntity<P, C, MTS, ME>> {

    /**
     * 当前名称
     */
    private String serverName;

    /**
     * 连接地址
     * <p>
     * host:port
     */
    private List<String> hostPortS;


    /**
     * 默认生产者
     */
    private P producer;

    /**
     * 默认消费者
     */
    private C consumer;

    /**
     * 其余消费者组
     */
    private List<C> otherConsumerS;


    /**
     * 线程池中保留的线程数，即使它们是空闲的，除非{@code allowCoreThreadTimeOut}被设置
     * <p>
     * the number of threads to keep in the pool, even if they are idle, unless {@code allowCoreThreadTimeOut} is set
     */
    private Integer corePoolSize = 2;
    /**
     * 池中允许的最大线程数
     * <p>
     * the maximum number of threads to allow in the pool
     */
    private Integer maximumPoolSize = 5;
    /**
     * 当线程数大于核心数时，这是剩余空闲线程在终止前等待新任务的最大时间。
     * <p>
     * when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.
     */
    private Long keepAliveTime = 100L;
    /**
     * {@code keepAliveTime}参数的时间单位
     * <p>
     * the time unit for the {@code keepAliveTime} argument
     */
    private TimeUnit unit = TimeUnit.SECONDS;
    /**
     * 这个队列的容量
     * <p>
     * the capacity of this queue
     */
    private Integer capacity = 2000;

    /**
     * 校验MQ配置类
     *
     * @return
     */
    public boolean checkMqEntity() {

        if (StringUtil.StringUtilsBylang3.isEmpty(this.getServerName())) {
            log.error("mqEntity中ServerName为空，请查看配置文件");
            throw new IllegalStateException("mqEntity中ServerName为空，请查看配置文件");
        }

        if (CollectionUtil.isEmpty(this.getHostPortS())) {
            log.error("ServerName为：{}的mqEntity中[hostPortS]为空，请查看配置文件", this.getServerName());
            throw new IllegalStateException("ServerName为：" + this.getServerName() + "的mqEntity中[hostPortS]为空，请查看配置文件");
        }

        return this.checkMQProducer();
    }

    public boolean checkMQProducer() {
        if (ObjectUtil.ObjectUtilByLang3.isEmpty(this.getProducer())) {
            log.error("ServerName为：{}的mqEntity中[producer]为空，请查看配置文件", this.getServerName());
            throw new IllegalStateException("ServerName为：" + this.getServerName() + "的mqEntity中[producer]为空，请查看配置文件");
        }
        return Boolean.TRUE;
    }

    public boolean checkMQConsumer(C mqConsumer) {
        if (ObjectUtil.ObjectUtilByLang3.isEmpty(mqConsumer)) {
            log.warn("ServerName为：{}的mqEntity中[consumer]为空，请查看配置文件", this.getServerName());
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }


    /**
     * 生成MQTemplateS
     *
     * @return
     */
    public abstract MTS mqTemplateS() throws Exception;

    /**
     * 生成生产者
     *
     * @return
     */
    public abstract Object defaultMQProducer() throws Exception;

    /**
     * 生成消费者
     *
     * @param mqConsumer
     * @return
     */
    public abstract Object defaultConsumer(C mqConsumer) throws Exception;

}
